package com.cnbot.canapp;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.cnbot.canapp.listener.base.IBaseCANDataResultListener;
import com.cnbot.canapp.listener.healthy.HealthyOrdinaryListener;
import com.cnbot.canapp.utils.ICanCode;
import com.dc.android_can.CAN;
import com.dc.android_can.can.CanDataType;
import com.dc.android_can.can.CanUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Copyright (c) 2016--2019/1/24  Hunan Cnbot Co., Ltd. All Rights Reserved.
 *
 * @descriptoin CAN 通讯接口
 * @FileName: AndroidCanApi.java
 * @author: dc
 * @date: 2019/1/24 14:08
 * @version: 1.0
 */
public class AndroidCanApi {
	private static final String TAG = AndroidCanApi.class.getSimpleName();

	private boolean isCanConnect; //CAN总线连接状态
	private boolean isReadThread; //CAN总线数据接收标志位
	/**
	 * can设备是否打开
	 */
	private boolean isDeviceopened;

	// 添加监听集合
	private List<IBaseCANDataResultListener> listenersList = new ArrayList<>(); //监听集合
	private IBaseCANDataResultListener iBaseCANDataResultListener; //数据结果回调接口
	private HealthyOrdinaryListener healthyOrdinaryListener; // 其他健康传感器回调接口
	private CANReadThread canReadThread = null; //CAN总线数据接收线程

	private final int HANDLER_DATA = 0X01;
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			if (msg.what == HANDLER_DATA) {
				int id = msg.arg2;
				CanDataType canDataType = (CanDataType) msg.obj;
				sendCANReceiveListener(id, canDataType);
			}
		}
	};

	private static AndroidCanApi instanll = null;

	private AndroidCanApi() {

	}

	public static AndroidCanApi getInstanll() {
		if (instanll == null) {
			synchronized (AndroidCanApi.class) {
				if (instanll == null) {
					instanll = new AndroidCanApi();
				}
			}
		}
		return instanll;
	}

	/**
	 * @descriptoin	CAN总线初始化
	 * @author	dc
	 * @date 2018/6/6 10:46
	 * @return true  初始化成功
	 * ww 不能保证一次初始化就能成功
	 */
	public boolean CAN_Init() {
		if (isDeviceopened && isCanConnect) {
			return true;
		}
		//设备已打开
		if (isDeviceopened) {
			//初始化未成功
			if (!isCanConnect) {
				isCanConnect = CAN.init() > 0;
				Log.e(TAG, "初始化 = " + isCanConnect);
				if (isCanConnect) {
					canReadThread = new CANReadThread();
					canReadThread.start();
				}
			}
		} else {
			isDeviceopened = CanUtils.initDevice();
			Log.e(TAG, "CAN节点打开 = " + isDeviceopened);
			if (isDeviceopened) {
				isCanConnect = CAN.init() > 0;
				Log.e(TAG, "初始化 = " + isCanConnect);
				if (isCanConnect) {
					canReadThread = new CANReadThread();
					canReadThread.start();
				}
			}
		}

		return isCanConnect;
	}

	/**
	 * @descriptoin	CAN是否打开
	 * @author	dc
	 * @date 2018/6/7 11:49
	 * @return true 已打开
	 */
	public boolean CAN_IsOpen() {
		return isCanConnect;
	}

	/**
	 * @descriptoin	注册结果回调接口
	 * @author	dc
	 * @param listener
	 * @date 2018/6/7 14:31
	 */
	public void setCANReceiveListener(IBaseCANDataResultListener listener) {
		if (!listenersList.contains(listener)) {
			listenersList.add(listener);
		}
		//        IBaseCANDataResultListener = listener;
	}

	/**
	 * @descriptoin	根据监听器发送监听数据
	 * @author	dc
	 * @param
	 * @date 2018/11/15 11:03
	 */
	public void sendCANReceiveListener(int id, CanDataType canDataType) {
		for (IBaseCANDataResultListener listener : listenersList) {
			listener.onCanReceived(id, canDataType);
		}
	}

	/**
	 * @descriptoin	移除监听器
	 * @author	dc
	 * @param listener
	 * @date 2018/11/15 10:59
	 * @return false 失败
	 */
	public boolean removeCANReceiveListener(IBaseCANDataResultListener listener) {
		if (listenersList.size() > 0 && listener == null) {
			return false;
		}
		return listenersList.remove(listener);
	}

	/**
	 * @descriptoin	清空所有监听器
	 * @author	dc
	 * @date 2018/11/15 11:00
	 */
	public void cleanCANReceiveListener() {
		listenersList.clear();
	}

	/**
	 * @descriptoin	停止接收线程
	 * @author	dc
	 * @date 2018/6/7 14:30
	 */
	public void close() {

		isReadThread = true;

	}

	public class CANReadThread extends Thread {
		@Override
		public void run() {
			super.run();

			while (!isReadThread) {
				CanDataType canDataType = CanUtils.canRead();
				if (canDataType != null) {
					if ((byte) canDataType.id == (ICanCode.BUF_INTERACTIVE_CODE)) {
						//                        Log.e(TAG, "canDataType id = " + (byte)canDataType.id + " cmd = " + canDataType.cmdWord);
					}

					Message msg = handler.obtainMessage();
					msg.what = HANDLER_DATA;
					msg.arg2 = canDataType.id;
					msg.obj = canDataType;

					handler.sendMessage(msg);
				}
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
